﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Huirui.Cavan.Domain.Seedwork;
using Huirui.Cavan.Domain.MainBoundedContext.SearchModule;
using Huirui.Cavan.Application.Seedwork;
using Huirui.Cavan.Domain.MainBoundedContext.StockModule;
using Huirui.Cavan.Application.MainBoundedContext.SystemModule;
using Spring.Context.Support;
using Huirui.Cavan.Core.Extension;
using Huirui.Cavan.Domain.MainBoundedContext.SystemModule;
using Huirui.Cavan.Domain.MainBoundedContext.ReportModule;

namespace Huirui.Cavan.Application.MainBoundedContext.StockModule
{
    public class StockAppService : BaseAppService<Stock, string, StockSearch, IStockRepository>, IStockAppService
    {
        private IUnitTransferAppService UnitTransferAppService { get; set; }
        private IStockUnitAppService StockUnitAppService { get; set; }
        private IWareHouseAppService WareHouseAppService { get; set; }
        private IStockTypeAppService StockTypeAppService { get; set; }

        public override BoolGenericResult<Stock> AddOrUpdate(Stock entity)
        {
            Init();
            this.UnitTransferAppService = this.SpringContext.GetObject(StockModuleConst.UNITTRANSFERAPPSERVICE) as IUnitTransferAppService;
            this.StockUnitAppService = this.SpringContext.GetObject(StockModuleConst.STOCKUNITAPPSERVICE) as IStockUnitAppService;
            this.WareHouseAppService = this.SpringContext.GetObject(StockModuleConst.WAREHOUSEAPPSERVICE) as IWareHouseAppService;
            this.StockTypeAppService = this.SpringContext.GetObject(StockModuleConst.STOCKTYPEAPPSERVICE) as IStockTypeAppService;

            BoolGenericResult<Stock> result = new BoolGenericResult<Stock>();
            if (entity.IsNull())
            {
                throw new ArgumentNullException("");
            }
            Employee employee = this.EmployeeAppService.GetBySearch(SearchFactory.CreateEmployeeSearch(SecurityAppService.UserAccount.Id)).FirstOrDefault();
            StockManager stockManager = new StockManager(employee);

            Stock oldStock = null;
            if (entity.Id.IsNotEmpty())
            {
                oldStock = this.Repository.Get(entity.Id);
            }
            if (entity.UnitTransfer.FromUnit.IsNotNull() && entity.UnitTransfer.FromUnit.Id > 0)
            {
                entity.UnitTransfer.FromUnit = this.StockUnitAppService.GetById(entity.UnitTransfer.FromUnit.Id);
                entity.StockUnit = entity.UnitTransfer.FromUnit;
            }
            if (entity.UnitTransfer.ToUnit.IsNotNull() && entity.UnitTransfer.ToUnit.Id > 0)
            {
                entity.UnitTransfer.ToUnit = this.StockUnitAppService.GetById(entity.UnitTransfer.ToUnit.Id);
            }
            entity.Type = this.StockTypeAppService.GetById(entity.Type.Id);
            entity.WareHouse = this.WareHouseAppService.GetById(entity.WareHouse.Id);
            if (entity.UnitTransfer.IsNotNull() && entity.UnitTransfer.FromUnit.Id > 0 && entity.UnitTransfer.ToUnit.Id > 0)
            {
                UnitTransfer unitTransfer = this.UnitTransferAppService.GetSingleBySearch(SearchFactory.CreateUnitTransferSearch(entity.UnitTransfer.FromUnit.Id,
                    entity.UnitTransfer.ToUnit.Id, entity.UnitTransfer.FromNumber, entity.UnitTransfer.ToNumber));
                if (unitTransfer.IsNull())
                {
                    BoolGenericResult<UnitTransfer> addUnitTransferResult = stockManager.AddUnitTransfer(entity.StockUnit, entity.UnitTransfer.ToUnit, entity.UnitTransfer.FromNumber, entity.UnitTransfer.ToNumber);
                    this.UnitTransferAppService.AddOrUpdate(addUnitTransferResult.Object);
                    unitTransfer = addUnitTransferResult.Object;
                }
                entity.UnitTransfer = unitTransfer;
            }

            if (oldStock.IsNull())
            {
                IIDGenerateAppService idGenerateAppService = this.SpringContext.GetObject(SystemModuleConst.IDGENERATEAPPSERVICE, new object[] { employee.Corporation }) as IIDGenerateAppService;
                entity.Id = idGenerateAppService.GenerateID(SystemIdentifier.BaseCodeRuleType.Stock);
                result = stockManager.AddStock(entity.Id, entity.Nature, entity.Name, entity.Specification, entity.Type, entity.StockUnit,
                    entity.BarCode, entity.IsProxy, entity.StandardPurchasePrice, entity.StandardSalesPrice,
                    entity.MaxPurchasePrice, entity.MinSalesPrice, entity.MinLeftNumber, entity.TaxRate, entity.WareHouse, entity.UnitTransfer);
                if (result.IsSuccess)
                    return base.Add(result.Object);
            }
            else
            {
                result = stockManager.UpdateStock(oldStock, entity.Nature, entity.Name, entity.Specification, entity.Type, entity.StockUnit,
                    entity.BarCode, entity.IsProxy, entity.StandardPurchasePrice, entity.StandardSalesPrice,
                    entity.MaxPurchasePrice, entity.MinSalesPrice, entity.MinLeftNumber, entity.TaxRate, entity.WareHouse);
                if (result.IsSuccess)
                    return base.Update(result.Object);
            }
            return result;
        }

        public IList<StockByPurchaseOrderReport> GetStocksByPurchaseOrderReport(DateTime? startDate, DateTime? endDate, string purchaseOrderCode, string supplierCode, string stockInStatues)
        {
            return this.Repository.GetStocksByPurchaseOrderReport(startDate, endDate, purchaseOrderCode, supplierCode, stockInStatues);
        }

        public IList<StockByPurchaseReport> GetStocskByStockInReport(DateTime? startDate, DateTime? endDate, string stockInCode, string stockCode)
        {
            return this.Repository.GetStocksByPurchaseReport(startDate, endDate, stockInCode, stockCode);
        }

        public IList<StockBySalesOrderReport> GetStocksBySalesOrderReport(DateTime? startDate, DateTime? endDate, string salesOrderCode, string customerCode, string stockOutStatues)
        {
            return this.Repository.GetStocksBySalesOrderReport(startDate, endDate, salesOrderCode, customerCode, stockOutStatues);
        }

        public IList<StockBySalesReport> GetStocksBySalesReport(DateTime? startDate, DateTime? endDate, string salesCode, string stockCode)
        {
            return this.Repository.GetStocksBySalesReport(startDate, endDate, salesCode, stockCode);
        }

        public IList<StockByWareHouseReport> GetStocksByWareHouseReport(string wareHouseCode, string stockCode)
        {
            return this.Repository.GetStocksByWareHouseReport(wareHouseCode, stockCode);
        }

        public override IEnumerable<Stock> GetBySearch(StockSearch searchParams, out long total)
        {
            if (searchParams.CustomerName.IsNotEmpty())
            {
                return this.Repository.GetStocksByCustomer(searchParams, out total);
            }
            else if (searchParams.SupplierName.IsNotEmpty())
            {
                return this.Repository.GetStocksBySupplier(searchParams, out total);
            }
            return base.GetBySearch(searchParams, out total);
        }
    }
}
